using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using FlatRedBall;
using FlatRedBall.Math;
using Microsoft.Xna.Framework;
using Xzipit.Utilities.Touch;
using System.Diagnostics;

namespace Xzipit.Utilities.Gestures
{
    public static class GameGestureManager
    {
        private const int MAX_TOUCHPOINTS_WINDOWS = 4;
        private static Dictionary<int, GameGesture> _dragGestures = new Dictionary<int, GameGesture>(MAX_TOUCHPOINTS_WINDOWS);
        private static List<GameGesture> _gestureBuffer = new List<GameGesture>(MAX_TOUCHPOINTS_WINDOWS);

        public static IEnumerable<GameGesture> Gestures
        {
            get;
            private set;
        }

        public static double LastScreenMoveTime
        {
            get;
            set;
        }

        public static void Update()
        {
            _gestureBuffer.Clear();

            SimultaneousGestureHelper.EnabledGestures = SimpleGestureType.FreeDrag | SimpleGestureType.DragComplete | SimpleGestureType.Tap | SimpleGestureType.Hold;

            SimultaneousGestureHelper.GenerateGestures();

            SimpleGestureSample simpleGesture;
            while (SimultaneousGestureHelper.IsGestureAvailable)
            {
                simpleGesture = SimultaneousGestureHelper.ReadGesture();
                GameGestureType newType = simpleGesture.SimpleGestureType.ToGameGestureType();
                Vector3 newPos = simpleGesture.Position.PixelToWorld(0.0f);


                if (_dragGestures.ContainsKey(simpleGesture.Id))
                {
                    GameGesture old = _dragGestures[simpleGesture.Id];

                    if (newType == GameGestureType.Drag)
                    {
                        _dragGestures.Remove(simpleGesture.Id);
                        _dragGestures.Add(
                            simpleGesture.Id,
                            new GameGesture(
                                newType,
                                old.Start,
                                newPos,
                                old.StartTime,
                                old.Id));
                    }
                    else if (newType == GameGestureType.Pull)
                    {
                        _dragGestures.Remove(simpleGesture.Id);
                        _gestureBuffer.Add(
                            new GameGesture(
                                newType,
                                old.Start,
                                old.End,
                                old.StartTime,
                                old.Id));
                    }
                    else
                    {
                        System.Diagnostics.Debug.WriteLine("HOW?");
                    }

                }
                else
                {
                    GameGesture newGesture = new GameGesture(newType, newPos, newPos, TimeManager.CurrentTime, simpleGesture.Id);

                    if (newType == GameGestureType.Drag)
                    {
                        _dragGestures.Add(simpleGesture.Id, newGesture);
                    }
                    else if (newType == GameGestureType.Tap
                        || newType == GameGestureType.Hold)
                    {
                        _gestureBuffer.Add(newGesture);
                    }
                }
            }

            foreach (GameGesture drag in _dragGestures.Values)
            {
                _gestureBuffer.Add(drag);
            }

            if (_gestureBuffer.Count > 1)
            {
                GameGesture pinch = new GameGesture();
                GameGesture g1 = new GameGesture();
                GameGesture g2 = new GameGesture();

                foreach (GameGesture g in _gestureBuffer)
                {
                    if (g.GameGestureType == GameGestureType.Drag
                        || g.GameGestureType == GameGestureType.Pull
                        || g.GameGestureType == GameGestureType.Hold)
                    {
                        foreach (GameGesture d in _gestureBuffer)
                        {
                            //if (d.GameGestureType == GameGestureType.Drag
                            //    || d.GameGestureType == GameGestureType.Pull)
                            //{
                            if (g.Id != d.Id)
                            {
                                GameGesturePair gPair = new GameGesturePair(g, d);

                                if (gPair.IsPinch)
                                {
                                    pinch = new GameGesture(GameGestureType.Pinch,
                                                            g.Start,
                                                            GameGesture.GetAveragePosition(g, d),
                                                            g.StartTime,
                                                            g.Id);
                                    g1 = g;
                                    g2 = d;
                                    break;
                                }
                            }
                        }
                        //}
                    }
                    if (g1.Equals(g))
                    {
                        break;
                    }
                }

                if (pinch.StartTime > 0)
                {
                    _dragGestures.Remove(g1.Id);
                    _dragGestures.Remove(g2.Id);
                    _gestureBuffer.Remove(g1);
                    _gestureBuffer.Remove(g2);
                    _gestureBuffer.Add(pinch);
                }
            }

            Gestures = _gestureBuffer.OrderBy(gesture => gesture.StartTime);
        }
    }
}
